package com.tianlh.service.impl.redis;

import java.io.IOException;
import java.util.List;
import java.util.UUID;

import redis.clients.jedis.*;

/**
 * @author 黑子
 * @Date 2017/12/30 15:34
 */
public class SimpleLock {

    public String acquireLock(Jedis conn, String lockname, Integer acquireTimeout, Integer lockTimeout) {

        String identifier = UUID.randomUUID().toString().replace("-", "");
        long end = System.currentTimeMillis() + acquireTimeout;
        while (System.currentTimeMillis() < end) {
            if (conn.setnx(lockname, identifier) == 1) {
                conn.expireAt(lockname, lockTimeout);
                return identifier;
            } else if (conn.ttl(lockname) == -1) {
                // -2已经过期 -1没有设置过期时间，永不失效
                conn.expire(lockname, lockTimeout);
            }

            try {
                Thread.sleep(1L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public boolean releaseLock(Jedis conn, String lockName, String identifier) {

        while (true) {
            conn.watch(lockName);
            if (conn.get(lockName).equals(identifier)) {
                redis.clients.jedis.Transaction transaction = conn.multi();
                Response<String> response = transaction.watch("");
                // 如果WATCH失败，则重试
                if(!"OK".equals(response.get())){
                    continue;
                }
                transaction.del(lockName);
                List<Object> exec = transaction.exec();
                if (exec.get(0).equals("OK")) {
                    try {
                        transaction.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    return true;
                }
            }
            break;
        }
        return false;
    }
}
